#include "CHttpReqBLOB.h"
#include <stdexcept>
#include <sstream>
#include <wx/buffer.h>
#include "Utils.h"

CHttpReqBLOB::CHttpReqBLOB(const bool auth_IN ,
                            const int retrySec_IN,
                            const int timeOutSec_IN)
:CHttpReq (auth_IN, retrySec_IN, timeOutSec_IN),blobMemBuf(0)
{

}

CHttpReqBLOB:: ~CHttpReqBLOB()
{
    if(blobMemBuf != NULL)
    {
        delete blobMemBuf;
        blobMemBuf = NULL;
    }
}



bool CHttpReqBLOB::startReqBLOB(const wxString& urlStr_IN)
{
    using std::runtime_error;
    size_t stream_size = 0;

    //Clear Memory Buffer
    if(blobMemBuf != NULL)
    {
        delete blobMemBuf;
        blobMemBuf = NULL;
    }

    //1.Http Req
    splitURL(urlStr_IN);
    retryConn(destHost);
    httpStream = httpReq.GetInputStream(destPath);

/*

    if(httpReq.GetError() != wxURL_NOERR)
    {
        #ifdef BLOB_REQ_LOG
            wxString errorTypeDescription("");
            switch(httpReq.GetError())
            {
                case wxURL_NOERR:
                    errorTypeDescription = "no error";
                    break;
                case wxURL_SNTXERR:
                    errorTypeDescription = "URL syntax error";
                    break;
                case wxURL_NOPROTO:
                    errorTypeDescription = "no protocol";
                    break;
                case wxURL_NOHOST:
                    errorTypeDescription = "no host";
                    break;
                case wxURL_NOPATH:
                    errorTypeDescription = "no path";
                    break;
                case wxURL_CONNERR:
                    errorTypeDescription = "connection error";
                    break;
                case wxURL_PROTOERR:
                    errorTypeDescription = "protocol error";
                    break;
                default:
                    errorTypeDescription = "unknown error";
            }
            logger.logError(wxString("When fetch avatar jpg, http req protocol error : ")
                                <<errorTypeDescription);
        #endif//BLOB_REQ_LOG
    }

*/

    try
    {
        httpErrCode = httpReq.GetResponse();
        if (httpErrCode == OK && httpStream != NULL)
        {
            //2. Read stream
            stream_size = httpStream->GetSize();
            blobMemBuf = new wxMemoryBuffer(stream_size);
            /*******Memory Buffer Won't Update*****************
            * Here use the header ptr of Memory Buffer to directly write.
            * The MemoryBuffer::GetDataLen() only updates when using append
            * Otherwise , using UngetWriteBuf() to manually set current size
            ************************************************/
            httpStream->Read(blobMemBuf->GetWriteBuf(stream_size), stream_size);
            blobMemBuf->UngetWriteBuf(stream_size);
            //3.Detect incomplete stream read
            if(httpStream->LastRead() != stream_size)
            {
                switch(httpStream->GetLastError())
                {
                    case wxSTREAM_EOF:
                        throw runtime_error("When fetch a blob, read http stream failed: EOF reached");
                        break;
                    case wxSTREAM_READ_ERROR:
                        throw runtime_error("When fetch a blob, read http stream failed: read error");
                        break;
                    default:
                        throw runtime_error("When fetch a blob, read http stream failed: unknown error");
                }
            }//end of if(stream read incomplete)

            //4. Successful
            wxDELETE(httpStream);
            return true;
        }
        else
        {
            std::ostringstream strStream;
            strStream<<"When fetch a blob, http req error code: "<<httpErrCode;
            throw runtime_error(strStream.str());
        }//end of if(http OK)
    }
    catch(runtime_error& e)
    {
        #ifdef BLOB_REQ_LOG
            LOGMAN.logError(e.what());
        #endif
        if(httpStream != NULL) wxDELETE(httpStream);
        return false;
    }//end of try

}//end of bool CHttpReq::startReq()

wxMemoryBuffer* CHttpReqBLOB::getMemBuf()
{
    return blobMemBuf;
}
